<?php
class XFramework {
	/**
	 * @var array
	 * <pre>
	 * array(
	 * 	'className' => 'classPath',
	 * 	'className2' => 'classPath2',
	 * )
	 * </pre>
	 */
	public static $importList = array();
	
	/**
	 * @var array
	 * <pre>
	 * array(
	 * 	'aliasName' => 'realpath',
	 * 	'aliasName' => 'realpath',
	 * )
	 * </pre>
	 */
	public static $pathAlias = array();
	
	/**
	 * @param string $path 'xxx.yyy.zzz'
	 * @param string $name
	 */
	public static function import( $path, $name='' ){
		$path = explode('.', $path);
		
		if ( '' == $name ) {
			$name = $path[count($path)-1];
		}
		
		foreach ($path as $key => $value){
			$path[$key] = self::getPathByAliaName($value);
		}
		
		$path = implode('/', $path).'.php';
		
		if ( in_array($name, self::$importList) ){
			return ;
		}
		
		self::$importList[$name] = $path;
		
		return;
	}
	
	/**
	 * @param string $name
	 * @param boolean $returnError
	 * @throws Exception
	 * @return string | boolean
	 */
	public static function getClassRealPath($name, $returnError=false){
		if ( isset(self::$importList[$name]) )
			return self::$importList[$name];
		else if ( $returnError )
			return false;
		else
			throw new Exception('Coulf not find class '.$name.' !');
	}
	
	/**
	 * Rename a path 
	 * 
	 * @param string $path
	 * @param string $name
	 * @param bool $cover
	 */
	public static function pathAlias( $path, $name, $cover='false' ){
		if ( !in_array($name, self::$pathAlias) || $cover ){
			self::$pathAlias[$name] = $path;
		}
		else {
			throw new Exception($name.' is already in the list !');
		}
	}
	
	/**
	 * Get the real path by alia name
	 * if there is no alia name in the list and set the $default as false
	 * an error would be throwed. or $default is seted as true and not alia
	 * name in the list, the $name will be returned.
	 * if the alia does in the list, the real path will be returned.
	 * 
	 * @param string $name
	 * @param bool $default
	 */
	public static function getPathByAliaName($name, $default=true){
		if ( isset(self::$pathAlias[$name]) )
			return self::$pathAlias[$name];
		
		if ( $default ) {
			return $name;
		}
		else {
			throw new Exception( 'Could not file the path in the list.' );
		}
	}
	
	/**
	 * The request looks like r=class/method.
	 * If everything is okay, the X would create a new object by new class and run the method
	 * by request.
	 * If there is no method in the request, is would try call class->defaultAction() to get 
	 * the default method and run it, but if method defaultAction does not exists, X would throw
	 * an error which could not find the handler.
	 * At last, if there is not r in the requrst, X would set the r request as the default
	 * action which defined in X.ini item [app][index].
	 */
	public function run(){
		$handler = null;
		if ( !isset($_REQUEST['r']) ){
			$_REQUEST['r'] = X::app()->config['app']['index'];
		}
		
		if ( count($handler = explode('/', $_REQUEST['r']))){
			if ( '.' == X::app()->config['app']['handlerPath'] ){
				X::import('Application.'.$handler[0].'.'.$handler[0]);
			}
			else {
				X::import('Application.'.X::app()->config['app']['handlerPath'].'.'.$handler[0].'.'.$handler[0]);
			}
			
			if ( 1 == count($handler) ){
				$handler = new $handler[0]();
				if ( method_exists($handler, 'defaultAction') ){
					$action = $handler->defaultAction();
				}
				else {
					throw new Exception('Could not find handler '.$_REQUEST['r']);
				}
			}
			else {
				$action = $handler[1];
				$handler = new $handler[0]();
				if ( method_exists($handler, $action) ){
					$action = $handler->$action();
				}
				else {
					throw new Exception('Could not find handler '.$_REQUEST['r']);
				}
			}
		}
	}
}